package handler

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"

	"log"
	"main/internal/dao"
	"main/internal/model"
)

// websocket接收参数
type WsReq struct {
	Cmd  string      `json:"cmd"`
	Data interface{} `json:"data"`
}

// Online结构体
type OnlineS struct {
}

// 一对一发送信息的结构体
type SendS struct {
	ToUserId uint   `json:"toUserId"`
	Content  string `json:"content"`
}

type WsSendReq struct {
	Cmd  string `json:"cmd"`
	Data SendS  `json:"data"`
}

// Onlinesocket接收参数
type WsOnLineReq struct {
	Cmd  string  `json:"cmd"`
	Data OnlineS `json:"data"`
}

type WsResp struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func GetSuccessResp(conn *websocket.Conn, data interface{}) {
	resp := WsResp{
		Code: 200,
		Msg:  "ok",
		Data: data,
	}

	respByte, _ := json.Marshal(resp)

	_ = conn.WriteMessage(websocket.TextMessage, respByte)

}

func GetFailResp(conn *websocket.Conn, code int, msg string) {
	resp := WsResp{
		Code: code,
		Msg:  msg,
		Data: nil,
	}

	respByte, _ := json.Marshal(resp)

	_ = conn.WriteMessage(websocket.TextMessage, respByte)
}

func Ws(c *gin.Context) {
	var upgrader = websocket.Upgrader{} // use default options

	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) //http 升级成websocket

	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer conn.Close()

	OnlineUserMap[c.GetUint("userId")] = conn
	fmt.Println(OnlineUserMap)
	for {

		_, message, err := conn.ReadMessage()

		if err != nil {
			log.Println("read:", err)
			break
		}
		var req WsReq

		err = json.Unmarshal(message, &req)
		if err != nil {
			GetFailResp(conn, 500, "指令解析失败")
			continue
		}

		switch req.Cmd {
		case "online":
			onlineUser(conn, message, c.GetUint("userId"))
		case "send":
			sendUser(conn, message, c.GetUint("userId"))
		default:
			GetFailResp(conn, 500, "没有该指令")
		}
	}
}

var OnlineUserMap = make(map[uint]*websocket.Conn)

func sendUser(conn *websocket.Conn, message []byte, userId uint) {
	var req WsSendReq
	err := json.Unmarshal(message, &req)
	if err != nil {
		GetFailResp(conn, 500, "发送信息指令错误")
		return
	}

	toUserIdConn := OnlineUserMap[req.Data.ToUserId]
	if toUserIdConn == nil {
		GetFailResp(conn, 500, "用户不在线")
		return
	}

	GetSuccessResp(toUserIdConn, req.Data.Content)
	GetSuccessResp(conn, "发送成功")

	chat := model.ChatHistory{
		FromUserId: userId,
		ToUserId:   req.Data.ToUserId,
		Content:    req.Data.Content,
		CType:      1,
	}

	chat.RoomId = genRoomId(chat.FromUserId, chat.ToUserId)

	dao.Create(&chat)

}

func genRoomId(forUserId uint, toUserId uint) uint {
	min := forUserId
	max := toUserId
	if max < min {
		min = toUserId
		max = forUserId
	}
	return min*1000000 + max
}

func onlineUser(conn *websocket.Conn, message []byte, userId uint) {
	var req WsOnLineReq
	err := json.Unmarshal(message, &req)
	if err != nil {
		GetFailResp(conn, 500, "上线指令错误")
		return
	}

	OnlineUserMap[userId] = conn
	fmt.Println(OnlineUserMap)
	GetSuccessResp(conn, "上线成功")
}
